package com.process.filter;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.process.controller.util.Account;
import com.process.dao.pojoDao.*;
import com.process.domain.publi.Teacher;
import com.process.domain.outer.OutTeacher;
import com.process.domain.publi.Admin;
import com.process.domain.publi.Company;
import com.process.domain.publi.Student;
import io.jsonwebtoken.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * @Description: token验证
 * @ClassName: JwtUtils
 * @Author: 殷凡卓
 * @Date: 2023/4/15 11:53
 */

@Component
@Slf4j
public class JwtUtils {

    /**
     * 过期时间5分钟
     */
    private static final long EXPIRE_TIME = 60 * 60 * 1000;
    /**
     * 加密密钥
     */
    private static final String KEY = "zhongyuangong";
    @Autowired
    private StudentDao studentDao;
    @Autowired
    private AdminDao adminDao;
    @Autowired
    private CompanyDao companyDao;
    @Autowired
    private OutTeacherDao outTeacherDao;
    @Autowired
    private TeacherDao teacherDao;

    /**
     * 生成token
     *
     * @param account 用户账号
     * @return
     */
    public String sign(Account account) {
        Map<String, Object> header = new HashMap();
        header.put("typ", "JWT");
        header.put("alg", "HS256");
        //设置账号信息
        //setExpiration:token过期时间  当前时间+有效时间
        //setIssuedAt:token创建时间
        //signWith:加密方式
        JwtBuilder builder = Jwts.builder().setHeader(header)
                .setId(account.getAccountUsername())
                .setAudience(account.getAccountIdentity())
                .setExpiration(new Date(System.currentTimeMillis() + EXPIRE_TIME))
                .setIssuedAt(new Date())
                .signWith(SignatureAlgorithm.HS256, KEY);
        return builder.compact();
    }

    /**
     * 验证token是否有效
     *
     * @param token 请求头中携带的token
     * @return token验证结果  2-token过期；1-token认证通过；0-token认证失败
     */
    public int verify(String token, HttpServletRequest request) {
        Claims claims = null;


        try {
            //token过期后，会抛出ExpiredJwtException 异常，通过这个来判定token过期，
            claims = Jwts.parser().setSigningKey(KEY).parseClaimsJws(token).getBody();
        } catch (ExpiredJwtException e) {
            return 2;
        }


        //从token中获取用户id，查询该Id的用户是否存在，存在则token验证通过
        String username = claims.getId();
        Integer identity = Integer.parseInt(claims.getAudience());

        log.info("identity:" + identity);

        Object account = new Object();
        if (identity == 1) {
             account = studentDao.selectOne(new QueryWrapper<Student>().eq("stu_phone", username));
        } else if (identity == 2) {
             account = teacherDao.selectOne(new QueryWrapper<Teacher>().eq("teacher_phone", username));
        } else if (identity == 3) {
             account = outTeacherDao.selectOne(new QueryWrapper<OutTeacher>().eq("teacher_phone", username));
        } else if (identity == 4) {
             account = adminDao.selectOne(new QueryWrapper<Admin>().eq("admin_phone", username));
        } else if (identity == 5) {
             account = companyDao.selectOne(new QueryWrapper<Company>().eq("company_phone", username));
        }


//        Account account = accountDao.selectOne(new QueryWrapper<Account>().eq("account_username", accountUsername));

        log.warn("Token信息:" + account);


        if (account != null) {
            // token正确 将identity和username记录到request中
            log.info("设置Attribute");
            request.setAttribute("username", username);
            request.setAttribute("identity", identity);
            return 1;
        } else {
            //token 错误
            return 0;
        }
    }
}
